// Copyright (C) 2005 Jayaram Mudigonda <jram@cs.utexas.edu>
//                    Taylor L. Riché <riche@cs.utexas.edu>
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// $Id: fivetuple.hh 229 2005-09-20 15:20:17Z richetl $
//
// -----------------------------------------------------------------

#ifndef FIVETUPLE_H
#define FIVETUPLE_H

#include <string.h>
#include <netinet/in.h>

#ifdef TT_BUILD
#include "prettyprint.hh"
#else
#include <tracetools/prettyprint.hh>
#endif

namespace tt {

class IPAddress
{
  unsigned int internalRep;
public:
  IPAddress(unsigned int raw) : internalRep(raw) {}
  ~IPAddress() {}
  inline int getIR() const {return internalRep;}
};

struct FiveTuple {
  unsigned int    saddr;
  unsigned int    daddr;
  unsigned short  sport;
  unsigned short  dport;
  unsigned short  proto;
};

  struct SixFiveTuple {
    in6_addr saddr;
    in6_addr daddr;
    unsigned short sport;
    unsigned short dport;
    unsigned short proto;
  };

class CompFiveTuple {

public:

  static bool saddr;
  static bool daddr;
  static bool proto;
  static bool sport;
  static bool dport;


  bool operator() (const FiveTuple x, const FiveTuple y) 
  {
    char    buf1[sizeof(FiveTuple)];
    char    buf2[sizeof(FiveTuple)];
    char    *ptr1 = buf1;
    char    *ptr2 = buf2;

    if(saddr) {
      memcpy(ptr1, (void *)(&(x.saddr)), sizeof(x.saddr));
      memcpy(ptr2, (void *)(&(y.saddr)), sizeof(y.saddr));
      ptr1 += sizeof(x.saddr);
      ptr2 += sizeof(y.saddr);
    }
    if(daddr) {
      memcpy(ptr1, (void *)(&(x.daddr)), sizeof(x.daddr));
      memcpy(ptr2, (void *)(&(y.daddr)), sizeof(y.daddr));
      ptr1 += sizeof(x.daddr);
      ptr2 += sizeof(y.daddr);
    }
    if(sport) {
      memcpy(ptr1, (void *)(&(x.sport)), sizeof(x.sport));
      memcpy(ptr2, (void *)(&(y.sport)), sizeof(y.sport));
      ptr1 += sizeof(x.sport);
      ptr2 += sizeof(y.sport);
    }
    if(dport) {
      memcpy(ptr1, (void *)(&(x.dport)), sizeof(x.dport));
      memcpy(ptr2, (void *)(&(y.dport)), sizeof(y.dport));
      ptr1 += sizeof(x.dport);
      ptr2 += sizeof(y.dport);
    }
    if(proto) {
      memcpy(ptr1, (void *)(&(x.proto)), sizeof(x.proto));
      memcpy(ptr2, (void *)(&(y.proto)), sizeof(y.proto));
      ptr1 += sizeof(x.proto);
      ptr2 += sizeof(y.proto);
    }

    return(memcmp(buf1, buf2, (size_t)(ptr1 - buf1)) < 0);
  }

};

class CompSixFiveTuple {

public:

  static bool saddr;
  static bool daddr;
  static bool proto;
  static bool sport;
  static bool dport;


  bool operator() (const SixFiveTuple x, const SixFiveTuple y) 
  {
    char    buf1[sizeof(SixFiveTuple)];
    char    buf2[sizeof(SixFiveTuple)];
    char    *ptr1 = buf1;
    char    *ptr2 = buf2;

    if(saddr) {
      memcpy(ptr1, (void *)(&(x.saddr)), sizeof(x.saddr));
      memcpy(ptr2, (void *)(&(y.saddr)), sizeof(y.saddr));
      ptr1 += sizeof(x.saddr);
      ptr2 += sizeof(y.saddr);
    }
    if(daddr) {
      memcpy(ptr1, (void *)(&(x.daddr)), sizeof(x.daddr));
      memcpy(ptr2, (void *)(&(y.daddr)), sizeof(y.daddr));
      ptr1 += sizeof(x.daddr);
      ptr2 += sizeof(y.daddr);
    }
    if(sport) {
      memcpy(ptr1, (void *)(&(x.sport)), sizeof(x.sport));
      memcpy(ptr2, (void *)(&(y.sport)), sizeof(y.sport));
      ptr1 += sizeof(x.sport);
      ptr2 += sizeof(y.sport);
    }
    if(dport) {
      memcpy(ptr1, (void *)(&(x.dport)), sizeof(x.dport));
      memcpy(ptr2, (void *)(&(y.dport)), sizeof(y.dport));
      ptr1 += sizeof(x.dport);
      ptr2 += sizeof(y.dport);
    }
    if(proto) {
      memcpy(ptr1, (void *)(&(x.proto)), sizeof(x.proto));
      memcpy(ptr2, (void *)(&(y.proto)), sizeof(y.proto));
      ptr1 += sizeof(x.proto);
      ptr2 += sizeof(y.proto);
    }

    return(memcmp(buf1, buf2, (size_t)(ptr1 - buf1)) < 0);
  }

};
}
#endif
